home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / AECUR100.ARJ / ALERT.C < prev    next >
C/C++ Source or Header  |  1990-03-09  |  6KB  |  257 lines

  1. /*----------------------------------------------------------------------
  2.  *
  3.  *  alert.c 
  4.  *
  5.  *  copyright (c) 1987,88,89,90 J. Alan Eldridge
  6.  *
  7.  *  DESCRIPTION:
  8.  *
  9.  *  a Mac-like alert box for Curses!
  10.  *
  11.  *  BUGS:
  12.  *
  13.  *  maximum length of text supplied by caller is A_UROWS * A_UCOLS
  14.  *      no checking is done for overflow in alertf
  15.  *      but it has A_USLOP extra bytes just in case
  16.  *      alerts truncates the text to fit
  17.  *
  18.  *  maximum length of a word is A_UCOLS 
  19.  *      alerts doesn't check for this error
  20.  *      but it could address outside the buffer
  21.  *      and mess up the stack
  22.  *  
  23.  *
  24.  *----------------------------------------------------------------------
  25.  */
  26.  
  27. #include <stdarg.h>
  28.  
  29. #include "curses.h"
  30.  
  31. /* args to newwin */
  32.  
  33. #define A_ROWS  12  /* # rows in window */
  34. #define A_COLS  60  /* # cols in window */
  35. #define A_ORGY  7   /* window has origin at ... */
  36. #define A_ORGX  10  /* ... row A_ORGY, col A_ORGX */
  37.  
  38. /* user text area */
  39.  
  40. #define A_UROWS 5   /* # rows in message area */
  41. #define A_UCOLS 50  /* # cols in message area */
  42. #define A_UORGY 2   /* message are has origin at ... */
  43. #define A_UORGX 5   /* ... row A_UORGY, col A_UORGX */
  44. #define A_USLOP 50  /* extra room in buffer so we don't overflow */
  45.  
  46. /* size of local buffer for alertf() */
  47.  
  48. #define A_UBUFSIZE  (A_UROWS * A_UCOLS + 1 + A_USLOP)
  49.  
  50. static  int     attrib = VID_DEFBRIGHT;  /* attribute to use for alert window */
  51.  
  52. int
  53. alertf(
  54.     int     die,
  55.     char    *title, 
  56.     char    *prompt,
  57.     int     *keys,
  58.     int     sound,
  59.     char    *fmt,
  60.     ...)
  61. {
  62.     va_list ap;
  63.     char    buf[A_UBUFSIZE];
  64.     
  65.     va_start(ap, fmt);
  66.     vsprintf(buf, fmt, ap);
  67.     va_end(ap);
  68.  
  69.     return alerts(die, title, prompt, keys, sound, buf);
  70. }
  71.  
  72. static char *
  73. getword(buf, lenp, nxtp)
  74. char *buf, **nxtp;
  75. int *lenp;
  76. {
  77.     char *cp;
  78.  
  79.     /* 
  80.         skip leading whitespace
  81.         except for newlines 
  82.     */
  83.  
  84.     while (*buf && isspace(*buf))
  85.         if (*buf == '\n') {
  86.             *lenp = 0;
  87.             *nxtp = buf + 1;
  88.             return buf;
  89.         } else
  90.             buf++;
  91.  
  92.     /*
  93.         collect the word,
  94.         if there is one,
  95.         and set the length
  96.     */
  97.     
  98.     cp = buf;
  99.     while (*cp && !isspace(*cp))
  100.         cp++;
  101.     *lenp = cp - buf;
  102.  
  103.     /* 
  104.         skip trailing whitespace,
  105.         stopping for a newline
  106.     */
  107.             
  108.     while (*cp && isspace(*cp))
  109.         if (*cp == '\n')
  110.             break;
  111.         else
  112.             cp++;
  113.             
  114.     *nxtp = cp;
  115.     return *lenp ?  buf : 0;
  116. }
  117.             
  118. void
  119. alertattr(att)
  120. int att;
  121. {
  122.     if (iscolor())
  123.         attrib = att != -1 ? att : __DEFBRIGHT;
  124. }
  125.     
  126. int
  127. alerts(die, title, prompt, keys, sound, s)
  128. int     die;
  129. char    *title, 
  130.         *prompt;
  131. int     *keys;
  132. int     sound;
  133. char    *s;
  134. {
  135.     static int nl[] = { K_NL, K_ILLEGAL };
  136.     static int nl_esc[] = { K_NL, K_ESC, K_ILLEGAL };
  137.     
  138.     int uy = 0, ux = 0, wlen, key;
  139.     char ubuf[A_UROWS][A_UCOLS + 1], *word;
  140.     WINDOW *awin, *asav, *newwin(), *savescr();
  141.  
  142.     /* allocate space */
  143.     
  144.     if (!(awin = newwin(A_ROWS, A_COLS, A_ORGY, A_ORGX)))
  145.         return ERR;
  146.     if (!(asav = savescr(A_ROWS, A_COLS, A_ORGY, A_ORGX))) {
  147.         delwin(awin);
  148.         return ERR;
  149.     }
  150.     
  151.     /*  set up the window */
  152.     
  153.     setattr(awin, attrib);
  154.     werase(awin);
  155.     
  156.     if (sound < 0)
  157.         wblinkon(awin);
  158.     box(awin, 1, 1);
  159.     if (title) {
  160.         mvwaddch(awin, 0, 2, ' ');
  161.         waddstr(awin, title);
  162.         waddch(awin, ' ');
  163.     }
  164.     wblinkoff(awin);
  165.  
  166.     if (die)
  167.         prompt = "Sorry. Press any key to end program.";
  168.     else {
  169.         if (!prompt) {
  170.             prompt = "Press ENTER to continue ...";
  171.             keys = nl;
  172.         } else if (!keys)
  173.             keys = nl_esc;
  174.     }
  175.     
  176.     /* 
  177.         set up the user text ...
  178.         
  179.         this is a word wrap routine
  180.         
  181.         it follows the same rules as the
  182.         word wrap routine in the Mac Toolbox
  183.         
  184.         a "word" is any sequence of characters
  185.         that aren't whitespace.  a newline
  186.         causes an explicit wrap.
  187.     */
  188.  
  189.     while (word = getword(s, &wlen, &s))
  190.         if (!wlen) {
  191.             /* got a newline */
  192.             if (uy >= A_UROWS - 1)
  193.                 break; /* truncate */
  194.             ubuf[uy][ux] = 0;
  195.             ux = 0;
  196.             uy++;
  197.         }  else {
  198.             /* got a word */
  199.             /* does it fit? */
  200.             if (ux + wlen + (ux != 0) >= A_UCOLS) {
  201.                 /* nope */
  202.                 if (uy >= A_UROWS - 1)
  203.                     break; /* truncate */
  204.                 ubuf[uy][ux] = 0;
  205.                 ux = 0;
  206.                 uy++;
  207.             } 
  208.             /* copy it into ubuf */            
  209.             if (ux != 0)
  210.                 ubuf[uy][ux++] = ' ';
  211.             while (wlen-- > 0)
  212.                 ubuf[uy][ux++] = *word++;
  213.         }
  214.  
  215.     ubuf[uy++][ux] = 0;
  216.     while (uy < A_UROWS)
  217.         ubuf[uy++][0] = 0;
  218.         
  219.     /* put user text on window */
  220.     
  221.     for (uy = 0; uy < A_UROWS; uy++)
  222.         mvwaddstr(awin, uy + A_UORGY, A_UORGX, ubuf[uy]);
  223.  
  224.     mvwaddstr(awin, A_UORGY + A_UROWS + 2, A_UORGX, prompt);
  225.     
  226.     /* pop up & get a key */
  227.         
  228.     wrefresh(awin);
  229.     while (sound-- > 0)
  230.         beep();
  231.  
  232.     if (die) {
  233.         wgetch(awin);
  234.         endwin();
  235.         exit(die);
  236.     }
  237.     
  238.     
  239.     while (kb_matchkey(keys, key = wgetch(awin)) == -1)
  240.         ;
  241.     
  242.     restscr(asav);
  243.     delwin(awin);
  244.     delwin(asav);
  245.     return key;
  246. }
  247.     
  248. /*
  249.     set up video attributes
  250. */
  251.     
  252. void
  253. init_alerts(void)
  254. {
  255.     attrib = __DEFBRIGHT;
  256. }
  257.